package com.example.shutdown_v1.schedule;

import com.example.shutdown_v1.entity.Sensor;
import com.example.shutdown_v1.entity.SensorData;
import com.example.shutdown_v1.repository.SensorDataRepository;
import com.example.shutdown_v1.repository.SensorRepository;
import com.example.shutdown_v1.service.AlarmService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * 传感器离线检测定时任务
 * 定期检测长时间未上报数据的传感器，并生成告警
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class SensorOfflineDetectionScheduler {

    private final SensorRepository sensorRepository;
    private final SensorDataRepository sensorDataRepository;
    private final AlarmService alarmService;
    
    @Value("${sensor.offline.detection.enabled:true}")
    private boolean detectionEnabled;
    
    @Value("${sensor.offline.threshold-minutes:30}")
    private int offlineThresholdMinutes;
    
    /**
     * 定期检测传感器离线状态
     * 默认每10分钟执行一次
     * Cron表达式：0 0/10 * * * ? = 每10分钟执行一次
     */
    @Scheduled(cron = "${schedule.sensor-offline-detection.cron:0 0/10 * * * ?}")
    @Transactional
    public void detectOfflineSensors() {
        if (!detectionEnabled) {
            log.debug("[离线检测] 功能已禁用，跳过检测");
            return;
        }
        
        log.debug("[离线检测] 开始检测传感器离线状态...");
        
        try {
            // 获取所有活跃的传感器
            List<Sensor> activeSensors = sensorRepository.findByStatus(1);
            
            if (activeSensors.isEmpty()) {
                log.debug("[离线检测] 无活跃传感器，跳过检测");
                return;
            }
            
            LocalDateTime offlineThreshold = LocalDateTime.now().minusMinutes(offlineThresholdMinutes);
            int offlineCount = 0;
            int onlineCount = 0;
            
            for (Sensor sensor : activeSensors) {
                // 查询传感器最新一条数据
                Optional<SensorData> latestData = sensorDataRepository
                        .findFirstBySensorIdOrderByReceiveTimeDesc(sensor.getSensorId());
                
                if (latestData.isEmpty()) {
                    // 传感器从未上报过数据
                    log.debug("[离线检测] 传感器 {} 从未上报数据", sensor.getSensorId());
                    continue;
                }
                
                LocalDateTime lastDataTime = latestData.get().getReceiveTime();
                
                // 检查是否离线
                if (lastDataTime.isBefore(offlineThreshold)) {
                    // 传感器离线
                    if (!Boolean.TRUE.equals(sensor.getIsOffline())) {
                        // 状态从在线变为离线，创建告警
                        sensor.setIsOffline(true);
                        sensor.setLastOfflineTime(LocalDateTime.now());
                        sensorRepository.save(sensor);
                        
                        // 创建离线告警（仅当传感器已分配给店铺时）
                        if (sensor.getShopId() != null) {
                            alarmService.createSensorOfflineAlarm(sensor.getShopId(), sensor.getSensorId());
                        } else {
                            log.debug("[离线告警] 传感器 {} 未分配店铺，跳过告警创建", sensor.getSensorId());
                        }
                        
                        log.warn("[离线告警] 传感器 {} 已离线超过 {} 分钟，最后数据时间: {}", 
                                sensor.getSensorId(), offlineThresholdMinutes, lastDataTime);
                        offlineCount++;
                    }
                } else {
                    // 传感器在线
                    if (Boolean.TRUE.equals(sensor.getIsOffline())) {
                        // 状态从离线恢复为在线
                        sensor.setIsOffline(false);
                        sensor.setLastOnlineTime(LocalDateTime.now());
                        sensorRepository.save(sensor);
                        
                        log.info("[在线恢复] 传感器 {} 已恢复在线", sensor.getSensorId());
                    }
                    onlineCount++;
                }
            }
            
            if (offlineCount > 0 || log.isDebugEnabled()) {
                log.info("[离线检测] 完成 - 在线: {}, 新离线: {}, 总传感器: {}", 
                        onlineCount, offlineCount, activeSensors.size());
            }
            
        } catch (Exception e) {
            log.error("[离线检测] 检测失败", e);
        }
    }
    
    /**
     * 手动触发离线检测（用于测试或紧急检查）
     */
    public void manualDetection() {
        log.info("[手动检测] 触发传感器离线检测");
        detectOfflineSensors();
    }
}

